import { getObjectValue, getEnv } from '../../util/ObjectUtil.js'
import { createCodeEnv, isTrue } from '../../util/code.js'

/**
*对查看属性有没有v-bind
*@param {Hue} vm 创建的Hue实例
*@param {Object} vnode 虚拟dom树的根节点
*/
export function checkvbind(vm, vnode) {
  if (vnode.nodeType !== 1) {
    return
  }
  // 文本节点没有attribute,故getAttributeNames无效
  let attrNames = vnode.elm.getAttributeNames()
  for (const attrName of attrNames) {
    if (attrName.indexOf('v-bind:') === 0 || attrName.indexOf(':') === 0) {
      vbind(vm._data, vnode, attrName, vnode.elm.getAttribute(attrName))
    }
  }
}

/**
*对属性进行绑定
*@param {Object} dataObj data数组
*@param {Object} vnode 虚拟dom树的根节点
*@param {string} name 属性名
*@param {string} dataName 数据名
*/
function vbind(dataObj, vnode, name, dataName) {
  let attrname = name.split(':')
  let oldclass = ''
  if (attrname[1] === 'class') {
    oldclass = vnode.elm.getAttribute(attrname[1])
  }
  if (/^{[\w\W]+}$/.test(dataName)) {
    let expression = dataName.substring(1, dataName.length - 1)
    let expressionList = expression.split(',')
    let result = analysisExpress(dataObj, vnode, expressionList)
    vnode.elm.setAttribute(attrname[1], result + ' ' + oldclass)
  } else {
    let value = getObjectValue(dataObj, dataName)
    vnode.elm.setAttribute(attrname[1], value + ' ' + oldclass)
  }
}

/**
*对表达式进行分析
*@param {Object} dataObj data数组
*@param {Object} vnode 虚拟dom树的根节点
*@param {Array} expressionList 表达式数组
*/
function analysisExpress(dataObj, vnode, expressionList) {
  let result = ''
  //有表达式，所以要得到环境变量
  let envObj = getEnv(dataObj, vnode)
  //判断表达式真假
  let codeEnv = createCodeEnv(envObj)
  for (const expression of expressionList) {
    let site = expression.indexOf(':')
    if (site > -1) {
      let handleExpress = expression.substring(site + 1, expression.length)
      let codeBoolean = isTrue(codeEnv, handleExpress)
      if (codeBoolean) result += expression.substring(0, site) + ','
    } else {
      result += expression + ','
    }
  }
  //得到最终值
  if (result.length > 0) {
    result = result.substring(0, result.length - 1)
  }
  return result
}